package case21

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"log"
	"os"
	"time"
)

func Test() {
	fmt.Println("🎯示例二十一：分页查询")

	db, err := mysqlConnect()
	if err != nil {
		fmt.Println(err)
		return
	}

	if err := db.AutoMigrate(&UserCase21{}, &RoleCase21{}, &MenuCase21{}); err != nil {
		fmt.Println("自动创建表结构失败：", err)
		return
	}

	//// 创建数据
	//// 菜单
	//menuArr1 := []MenuCase21{
	//	{MenuName: "用户管理-列表"},
	//	{MenuName: "用户管理-列表-详情"},
	//	{MenuName: "订单管理-列表"},
	//	{MenuName: "订单管理-列表-详情"},
	//	{MenuName: "商品管理-列表"},
	//	{MenuName: "商品管理-列表-详情"},
	//	{MenuName: "类目管理-列表"},
	//	{MenuName: "类目管理-列表-详情"},
	//	{MenuName: "Banner管理-列表"},
	//	{MenuName: "Banner管理-列表-详情"},
	//}
	//db.Create(&menuArr1)
	//
	//// 角色
	//roleArr1 := []RoleCase21{
	//	{RoleName: "超级管理员"},
	//	{RoleName: "系统管理员"},
	//	{RoleName: "普通用户"},
	//	{RoleName: "管理员用户"},
	//}
	//db.Create(&roleArr1)
	//
	//// 用户
	//userArr1 := []UserCase21{
	//	{UserName: "lili", PassWord: "123"},
	//	{UserName: "zhangsan", PassWord: "123"},
	//	{UserName: "root", PassWord: "123"},
	//	{UserName: "system", PassWord: "123"},
	//	{UserName: "AAA", PassWord: "123"},
	//	{UserName: "王五", PassWord: "123"},
	//	{UserName: "小明", PassWord: "123"},
	//	{UserName: "小黄", PassWord: "123"},
	//	{UserName: "小散", PassWord: "123"},
	//	{UserName: "小卡", PassWord: "123"},
	//	{UserName: "小罗", PassWord: "123"},
	//	{UserName: "小蓝", PassWord: "123"},
	//	{UserName: "小空", PassWord: "123"},
	//}
	//db.Create(&userArr1)

	//// 查询
	//menuArr2 := []MenuCase21{}
	//db.Order("id asc").Find(&menuArr2)
	//for _, m := range menuArr2 {
	//	fmt.Println(m)
	//}
	//
	//roleArr2 := []RoleCase21{}
	//db.Order("id asc").Find(&roleArr2)
	//fmt.Println(roleArr2)
	//
	//userArr2 := []UserCase21{}
	//db.Order("id asc").Find(&userArr2)
	//for _, u := range userArr2 {
	//	fmt.Println(u)
	//}
	//
	//// 建立表关系
	//// 超级管理员 有 所有菜单
	//db.Model(&roleArr2[0]).Association("Menus").Append(&menuArr2)
	//// 系统管理员 有 所有菜单
	//db.Model(&roleArr2[1]).Association("Menus").Append(&menuArr2)
	//// 普通用户 有列表 无详情页面
	//db.Model(&roleArr2[2]).Association("Menus").Append(&menuArr2[0], &menuArr2[2], &menuArr2[4], &menuArr2[6])
	//// 管理员用户 有 菜单前8个的所有元素-包含8
	//menuArr2_ := menuArr2[:8]
	//db.Model(&roleArr2[3]).Association("Menus").Append(&menuArr2_)
	//
	//// 用户配置角色
	//// lili - 普通用户 -  管理员用户
	//db.Model(&userArr2[0]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[0]).Association("Roles").Append(&roleArr2[3])
	//// zhangsan - 普通用户
	//db.Model(&userArr2[1]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[6]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[7]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[8]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[9]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[10]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[11]).Association("Roles").Append(&roleArr2[2])
	//db.Model(&userArr2[12]).Association("Roles").Append(&roleArr2[2])
	//// root - 超级管理员
	//db.Model(&userArr2[2]).Association("Roles").Append(&roleArr2[0])
	//// system - 系统管理员
	//db.Model(&userArr2[3]).Association("Roles").Append(&roleArr2[1])
	//// AAA - 管理员用户
	//db.Model(&userArr2[4]).Association("Roles").Append(&roleArr2[3])

	// 预加载 关联查询用户 拥有的角色和菜单
	var userArr3 []UserCase21
	db.Preload("Roles").Preload("Roles.Menus").Find(&userArr3)
	for _, u := range userArr3 {
		fmt.Println(u.UserName)
		for _, r := range u.Roles {
			fmt.Println("\t 角色：", r.RoleName)
			for _, m := range r.Menus {
				fmt.Println("\t\t 菜单：", m.MenuName)
			}
		}
	}

	fmt.Println("----------------------------------------------------")

	//// 用户单表分页查询
	//paginator := NewPagination[UserCase21](db, 1, 3)
	//var name4 string = ""
	//if name4 != "" {
	//	paginator.Where("UserName Like ?", "%"+name4+"%")
	//}
	//
	//res, err := paginator.Order("id asc").Find()
	//if err != nil {
	//	fmt.Println(err)
	//}
	//fmt.Println(res.List)
	//fmt.Println(res.PageInfo)
	//// 打印
	//for _, u := range res.List {
	//	fmt.Printf("User: %+v\n", u)
	//}

	//// 用户单表分页查询-使用查询函数
	//pres, err := userPageSimple(db, 1, 3, "小")
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//fmt.Println(pres.List)
	//strjson, err := json.Marshal(pres)
	//if err != nil {
	//	fmt.Println("转json 字符串失败:", err)
	//	return
	//}
	//fmt.Println(string(strjson))
	//{"page_info":{"page":1,"page_size":3,"total":13,"total_pages":5,"has_prev":false,"has_next":true},
	//	"list":[{"ID":1,"UserName":"lili","PassWord":"123","State":0,"CreateTime":"2025-11-07T14:54:18+08:00","UpdateTime":"2025-11-07T14:54:18+08:00","Roles":null},{"ID":2,"UserName":"zhangsan","PassWord":"123","State":0,"CreateTime":"2025-11-07T14:54:18+08:00","UpdateTime":"2025-11-07T14:54:18+08:00","Roles":null},{"ID":3,"UserName":"root","PassWord":"123","State":0,"CreateTime":"2025-11-07T14:54:18+08:00","UpdateTime":"2025-11-07T14:54:18+08:00","Roles":null}]}

	fmt.Println("----------------------------------------------------")

	//多表关联分页查询
	// 查询所有用户拥有的角色列表
	//query := db.Model(&UserCase21{}).
	//	Select("user_case21.id, user_case21.user_name").
	//	Joins(`
	//		INNER JOIN user_role_case21 ON user_case21.id = user_role_case21.user_case21_id
	//		INNER JOIN role_case21 ON role_case21.id = user_role_case21.role_case21_id`)
	//res2, err := NewPagination[UserRoleresCase21](query, 1, 3).Order("user_case21.id asc").Find()
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	// 复杂关联查询 - 现在应该能正常工作了
	//query := db.Model(&UserCase21{}).
	//	Select("user_case21.id, user_case21.user_name").
	//	Joins(`
	//    INNER JOIN user_role_case21 ON user_case21.id = user_role_case21.user_case21_id
	//    INNER JOIN role_case21 ON role_case21.id = user_role_case21.role_case21_id`)
	//
	//res2, err := NewPagination[UserRoleresCase21](query, 1, 3).
	//	Order("user_case21.id asc"). // 明确指定去重字段
	//	Find()
	//
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//// 现在 result.List 是 []UserCase21 类型，可以直接使用
	//for _, user := range res2.List {
	//	fmt.Printf("User: %+v\n", user)
	//}

	fmt.Println("----------------------------------------------------")

	//// 查询lili用户拥有的菜单权限
	//query1 := db.Model(&UserCase21{}).
	//	Select("user_case21.user_name, menu_case21.id as 'menu_id', menu_case21.menu_name ").
	//	Joins(`
	//			INNER JOIN user_role_case21 ON user_case21.id = user_role_case21.user_case21_id
	//			INNER JOIN role_menu_case21 ON user_role_case21.role_case21_id = role_menu_case21.role_case21_id
	//			INNER JOIN menu_case21 ON menu_case21.id = role_menu_case21.menu_case21_id
	//		`)
	//res, err := NewPagination[UserMenuCase21](query1, 1, 5).Find()
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//for _, v := range res.List {
	//	fmt.Printf("User: %+v\n", v)
	//}

	fmt.Println(db)
}

// 初始化连接
func mysqlConnect() (*gorm.DB, error) {
	url := "root:123456@tcp(127.0.0.1:3306)/case1?charset=utf8mb4&parseTime=True&loc=Local"

	// 配置自定义 Logger 打印sql日志
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second, // 慢 SQL 阈值
			LogLevel:                  logger.Info, // 可以设置为不同级别 Silent-不打印任何日志 Error-只打印错误日志 Warn-打印慢查询和错误 Info-打印慢查询和错误
			IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound（记录未找到）错误
			Colorful:                  true,        // 彩色打印
		},
	)

	db, err := gorm.Open(mysql.Open(url), &gorm.Config{
		Logger: newLogger, // 设置 Logger
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 关闭默认，使用表名
		},
	})
	if err != nil {
		return nil, fmt.Errorf("mysql connect err: %v", err)
	}

	sqlDB, err := db.DB()
	if err != nil {
		panic("failed to get sql.DB")
	}

	// 配置连接池
	// 最大空闲连接数 - 应该小于最大打开连接数
	sqlDB.SetMaxIdleConns(20)
	// 最大打开连接数 - 根据应用负载和MySQL配置调整
	sqlDB.SetMaxOpenConns(100)
	// 连接最大生命周期 - 小于MySQL的wait_timeout设置
	sqlDB.SetConnMaxLifetime(5 * time.Minute)
	// 空闲连接最大存活时间
	sqlDB.SetConnMaxIdleTime(10 * time.Minute)

	return db, nil
}

// 结构体对象
// 用户 多对多 角色； 角色 多对多 菜单；

// 用户结构体
type UserCase21 struct {
	ID         int         `gorm:"primarykey;auto_increment" json:"id"`
	UserName   string      `gorm:"type:varchar(50);not null" json:"user_name"`
	PassWord   string      `gorm:"type:varchar(50);not null" json:"pass_word"`
	State      StateCase21 `gorm:"type:tinyint;default:0" json:"state"`                        //使用枚举
	CreateTime time.Time   `gorm:"type:datetime;autoCreateTime" json:"create_time"`            //自动设置创建时间
	UpdateTime time.Time   `gorm:"type:datetime;default:CURRENT_TIMESTAMP" json:"update_time"` //设置默认值
	//预处理
	//对应多角色
	Roles []RoleCase21 `gorm:"many2many:user_role_case21;"`
}

// 角色结构体
type RoleCase21 struct {
	ID       int    `gorm:"primarykey;auto_increment"`
	RoleName string `gorm:"type:varchar(50);uniqueIndex"`
	//对应多菜单
	Menus []MenuCase21 `gorm:"many2many:role_menu_case21;"`
	//对应多用户
	Users []UserCase21 `gorm:"many2many:user_role_case21;"`
}

// 菜单结构体
type MenuCase21 struct {
	ID       int    `gorm:"primarykey;auto_increment"`
	MenuName string `gorm:"type:varchar(50);uniqueIndex"`
	//对应多角色
	Roles []RoleCase21 `gorm:"many2many:role_menu_case21;"`
}

// 用户状态枚举 iota
type StateCase21 int

const (
	Normal StateCase21 = iota // 0: 正常
	Freeze                    // 1: 冻结
	Cancel                    // 2: 注销
	Stop                      // 3: 停用
)

//
//// 用户单表分页查询
//func userPageSimple(db *gorm.DB, pageNum, pageSize int, name string) (*PageResult[UserCase21], error) {
//
//	paginator := NewPagination[UserCase21](db, pageNum, pageSize)
//
//	if name != "" {
//		paginator.Where("user_name Like ?", "%"+name+"%")
//	}
//
//	res, err := paginator.Order("id asc").Find()
//	if err != nil {
//		return nil, err
//	}
//	//fmt.Println(res.List)
//	//fmt.Println(res.PageInfo)
//	return res, nil
//}

// 用户关联角色返回-结构体
type UserRoleresCase21 struct {
	ID       uint   `json:"id"`
	UserName string `json:"user_name"`
	RoleName string `json:"role_name"`
}

// 用户关联角色返回-结构体
type UserMenuCase21 struct {
	UserName string `json:"user_name"`
	MenuID   uint   `json:"menu_id"`
	MenuName string `json:"menu_name"`
}
